/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import model.Appointment;
import model.Campaign;
import model.Client;
import model.ConsultedCampaign;
import model.Resource;
import model.Skill;
import model.Task;
import model.user.Director;
import model.user.Governor;
import model.user.Staff;
import model.user.User;

/**
 *
 * @author CUNEYT
 */
public class Utilization {

    public static ArrayList<User> getUsers() {
        ArrayList<User> users = new ArrayList<User>();
        FileInputStream fstream = null;
        BufferedReader br = null;
        String line = null;
        String[] user = null;
        try {
            fstream = new FileInputStream("data/users.txt");
            br = new BufferedReader(new InputStreamReader(fstream));
            user = new String[5];
            while ((line = br.readLine()) != null) {
                user = line.split(",");
                user = trimAll(user);
                users.add(new User(user[0], user[1], user[2], user[3].toCharArray(), user[4]));
            }
            br.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, ex);
        } catch (java.io.IOException iox) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, iox);
        }

        return users;
    }

    public static ArrayList<Skill> getSkills() {
        ArrayList<Skill> skills = new ArrayList<Skill>();
        FileInputStream fstream = null;
        BufferedReader br = null;
        String line = null;
        String[] user = null;
        try {
            fstream = new FileInputStream("data/skills.txt");
            br = new BufferedReader(new InputStreamReader(fstream));
            user = new String[2];
            while ((line = br.readLine()) != null) {
                user = line.split(",");
                user = trimAll(user);
                skills.add(new Skill(user[0], Integer.parseInt(user[1])));
            }
            br.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, ex);
        } catch (java.io.IOException iox) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, iox);
        }
        return skills;
    }

    public static ArrayList<Staff> getStaff() {
        ArrayList<Staff> result = new ArrayList<Staff>();
        ArrayList<User> users = getUsers();
        for (Iterator<User> it = users.iterator(); it.hasNext();) {
            User user = it.next();
            if (user.getRole().equals(User.STAFF)) {
                Staff s = new Staff(user.getName(), user.getSurname(), user.getUsername(), user.getPassword());
                result.add(s);
            }
        }
        return result;
    }

    private static ArrayList<Governor> getGovernors() {
        ArrayList<Governor> result = new ArrayList<Governor>();
        ArrayList<User> users = getUsers();
        for (Iterator<User> it = users.iterator(); it.hasNext();) {
            User user = it.next();
            if (user.getRole().equals(User.GOVERNOR)) {
                result.add(new Governor(user.getName(), user.getSurname(), user.getUsername(), user.getPassword()));
            }
        }
        return result;
    }

    private static ArrayList<Director> getDirectors() {
        ArrayList<Director> result = new ArrayList<Director>();
        ArrayList<User> users = getUsers();
        for (Iterator<User> it = users.iterator(); it.hasNext();) {
            User user = it.next();
            if (user.getRole().equals(User.DIRECTOR)) {
                result.add(new Director(user.getName(), user.getSurname(), user.getUsername(), user.getPassword()));
            }
        }
        return result;
    }

    public static ArrayList<Client> getClients() {
        ArrayList<Client> clients = new ArrayList<Client>();

        FileInputStream fstream = null;
        BufferedReader br = null;
        String line = null;
        String[] client = null;
        try {
            fstream = new FileInputStream("data/clients.txt");
            br = new BufferedReader(new InputStreamReader(fstream));
            client = new String[4];
            while ((line = br.readLine()) != null) {
                client = line.split(",");
                client = trimAll(client);
                clients.add(new Client(client[0], client[1], client[2], client[3]));
            }
            br.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, ex);
        } catch (java.io.IOException iox) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, iox);
        }
        return clients;
    }

    private static ArrayList<Task> getTasks() {
        ArrayList<Task> result = new ArrayList<Task>();
        FileInputStream fis = null;
        BufferedReader br = null;
        String line = null;
        String[] app = null;

        try {
            fis = new FileInputStream("data/tasks.txt");
            br = new BufferedReader(new InputStreamReader(fis));
            app = new String[6];
            while ((line = br.readLine()) != null) {
                app = line.split(",");
                app = trimAll(app);
                result.add(new Task(app[0], setDate(app[1]), setDate(app[2]), app[3], app[4], app[5]));
            }
            br.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, ex);
        } catch (java.io.IOException iox) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, iox);
        }
        return result;
    }

    public static String formatDate(Date d) {
        return DateFormat.getDateInstance().format(d);
    }

    private static ArrayList<Appointment> getAppointments() {
        ArrayList<Appointment> result = new ArrayList<Appointment>();
        FileInputStream fis = null;
        BufferedReader br = null;
        String line = null;
        String[] app = null;

        try {
            fis = new FileInputStream("data/appointments.txt");
            br = new BufferedReader(new InputStreamReader(fis));
            app = new String[5];
            while ((line = br.readLine()) != null) {
                app = line.split(",");
                app = trimAll(app);
                result.add(new Appointment(app[0], setDate(app[1]), app[2], app[3], app[4]));
            }
            br.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, ex);
        } catch (java.io.IOException iox) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, iox);
        }
        return result;
    }

    private static ArrayList<Campaign> getCampaigns() {
        ArrayList<Campaign> result = new ArrayList<Campaign>();
        FileInputStream fis = null;
        BufferedReader br = null;
        String line = null;
        String[] app = null;

        try {
            fis = new FileInputStream("data/campaigns.txt");
            br = new BufferedReader(new InputStreamReader(fis));
            app = new String[5];
            while ((line = br.readLine()) != null) {
                app = line.split(",");
                app = trimAll(app);
                result.add(new Campaign(app[0], app[1], setDate(app[2]), setDate(app[3]), app[4]));
            }
            br.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, ex);
        } catch (java.io.IOException iox) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, iox);
        }
        return result;
    }

    public static ArrayList<Resource> getResources() {
        ArrayList<Resource> result = new ArrayList<Resource>();
        FileInputStream fis = null;
        BufferedReader br = null;
        String line = null;
        String[] app = null;

        try {
            fis = new FileInputStream("data/resources.txt");
            br = new BufferedReader(new InputStreamReader(fis));
            app = new String[2];
            while ((line = br.readLine()) != null) {
                app = line.split(",");
                app = trimAll(app);
                result.add(new Resource(app[0], Double.parseDouble(app[1])));
            }
            br.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, ex);
        } catch (java.io.IOException iox) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, iox);
        }
        return result;
    }

    private static Date setDate(String s) {
        GregorianCalendar date = new GregorianCalendar();
        date.set(Integer.parseInt(s.substring(s.length() - 4, s.length())),
                Integer.parseInt(s.substring(3, 5)), Integer.parseInt(s.substring(0, 2)));
        return date.getTime();
    }

    public static void addClient(String name, String gen_info, String con_person, String con_info) {
        FileOutputStream fstream = null;
        BufferedWriter bw = null;
        String line = name + "," + gen_info + "," + con_person + "," + con_info;
        try {
            fstream = new FileOutputStream("data/clients.txt", true);
            bw = new BufferedWriter(new OutputStreamWriter(fstream));
            bw.newLine();
            bw.write(line);
            bw.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void addUser(User usr) {
        FileOutputStream fstream = null;
        BufferedWriter bw = null;
        String line = usr.getName() + ", " + usr.getSurname() + ", " + usr.getUsername() + ", " + usr.getPassword() + ", " + usr.getRole();
        try {
            fstream = new FileOutputStream("data/users.txt", true);
            bw = new BufferedWriter(new OutputStreamWriter(fstream));
            bw.newLine();
            bw.write(line);
            bw.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void addSkill(String title, String level) {
        FileOutputStream fstream = null;
        BufferedWriter bw = null;
        String line = title + ", " + level;
        try {
            fstream = new FileOutputStream("data/skills.txt", true);
            bw = new BufferedWriter(new OutputStreamWriter(fstream));
            bw.newLine();
            bw.write(line);
            bw.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Utilization.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private static void prepareStaffCampaigns(Staff staff, ArrayList<Campaign> campaigns) {
        int max = 0;
        while (max < 1) {
            max = (int) (Math.random() * campaigns.size());
        }
        for (int i = 0; i < max; i++) {
            Campaign campaign = campaigns.get(i);
            campaign.assignStaff(staff);
            addInAndOutWorkHours(staff);
        }
    }

    private static void addInAndOutWorkHours(Staff s) {
        for (Iterator<ConsultedCampaign> it = s.getConsultedCampaigns().iterator(); it.hasNext();) {
            ConsultedCampaign cc = it.next();
            s.addInOfficeHour(cc, Math.random() * 10);
            s.addOutOfOfficeHours(cc, Math.random() * 5);
        }
    }

    private static void prepareStaffSchedule(Staff staff, ArrayList<Task> tasks, ArrayList<Appointment> apps) {
        int max = (int) (Math.random() * (tasks.size() - 1));
        for (int i = 0; i < max; i++) {
            staff.addTask(tasks.get(i));
        }
        max = (int) (Math.random() * (apps.size() - 1));
        for (int i = 0; i < max; i++) {
            staff.addAppointment(apps.get(i));
        }
    }

    public static void prepareDirector(Director dir) {
        ArrayList<Campaign> campaigns = Utilization.getCampaigns();
        ArrayList<Staff> staff = Utilization.getStaff();
        dir.setStaff(staff);
        dir.setResources(Utilization.getResources());
        int max = 0;
        for (Iterator<Campaign> it = campaigns.iterator(); it.hasNext();) {
            Campaign campaign = it.next();
            dir.addCampaign(campaign);
            campaign.setDirector(dir);
            campaign.addResource(new Resource("test Resource", 10));
        }
        while (max < 1) {
            max = (int) (Math.random() * staff.size());
        }
        for (int i = 0; i < max; i++) {
            prepareStaffCampaigns(staff.get(i), campaigns);
        }
    }

    public static void prepareStaff(Staff staff) {
        ArrayList<Task> tasks = Utilization.getTasks();
        ArrayList<Appointment> apps = Utilization.getAppointments();
        ArrayList<Campaign> camps = Utilization.getCampaigns();
        prepareStaffSchedule(staff, tasks, apps);
        prepareStaffCampaigns(staff, camps);
    }

    public static void prepareGovernor(Governor g) {
        ArrayList<Campaign> campaigns = Utilization.getCampaigns();
        ArrayList<Client> clients = Utilization.getClients();
        ArrayList<Staff> staff = Utilization.getStaff();
        ArrayList<Director> directors = Utilization.getDirectors();
        ArrayList<Task> tasks = Utilization.getTasks();
        ArrayList<Appointment> apps = Utilization.getAppointments();
        int max = 0;
        g.setCampaigns(campaigns);
        g.setStaff(staff);
        for (Iterator<Campaign> it = campaigns.iterator(); it.hasNext();) {
            Campaign campaign = it.next();
            campaign.setClient(clients.get((int) (Math.random() * (clients.size() - 1))));
            while (max < 1) {
                max = (int) (Math.random() * staff.size());
            }
            for (int i = 0; i < max; i++) {
                Staff s = staff.get(i);
                Utilization.prepareStaffSchedule(s, tasks, apps);
                campaign.assignStaff(s);
            }
            campaign.setDirector(directors.get((int) (Math.random() * (directors.size() - 1))));
            campaign.setResponsible(campaign.getStaff().get(0));
        }
    }

    private static String[] trimAll(String[] data) {
        for (int i = 0; i < data.length; i++) {
            data[i] = data[i].trim();
        }
        return data;
    }

    public static double formatDouble(double value) {
        DecimalFormat df = new DecimalFormat(".##");
        try {
            return df.parse(df.format(value)).doubleValue();
        } catch (ParseException ex) {
            return value;
        }
    }
}
